#include<user.h>
typedef struct ShareRes_t {
    Queue queue;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
}ShareRes;
typedef struct Node_s
{
    Node* next;
    int data;
}Node;
typedef struct queue_s
{
    Node* Head;
    Node* Tail;
    int Count;
}Queue;
int enQueue(Queue* queue, int val)
{
    Node* newnode = (Node*)calloc(1, sizeof(Node));
    newnode->data = val;
    if (queue->Count == 0)
    {
        queue->Head = newnode;
        queue->Tail = newnode;
    }
    else {
        queue->Tail->next = newnode;
        queue->Tail = newnode;
    }
    queue->Count++;
    return 0;
}

int DeQueue(Queue* queue)
{
    Node* curp = queue->Head;
    queue->Head = curp->next;
    if (queue->Head == NULL)
    {
        queue->Tail = NULL;
    }
    free(curp);
    queue->Count--;
    return 0;
}
int VistQueue(Queue* queue)
{
    Node* pcur = queue->Head;
    while (pcur != NULL)
    {
        printf("data is :%d  ", pcur->data);
        pcur = pcur->next;
    }
    printf("\n");
}
void* producer(void* arg)
{
    ShareRes* pres = (ShareRes*)arg;
    while (1)
    {
        pthread_mutex_lock(&pres->mutex);
        while (pres->queue.Count >= 10)
        {
            pthread_cond_wait(&pres->cond, &pres->mutex);
        }
        printf("producer,current queue count is %d\n", pres->queue.Count);
        int data = rand() % 1000;
        enQueue(&pres->queue, data);
        printf("data=%d\n", data);
        VistQueue(&pres->queue);
        printf("afeter producer,current queue is %d\n", pres->queue.Count);
        pthread_mutex_unlock(&pres->mutex);
        pthread_cond_broadcast(&pres->cond);
        sleep(3);
    }

}
void comsumer(void* arg)
{
    ShareRes* pres = (ShareRes*)arg;
    while (1)
    {
        pthread_mutex_lock(&pres->mutex);
        while (pres->queue.Count <= 0)
        {
            pthread_cond_wait(&pres->cond, &pres->mutex);
        }
        printf("cumsumer,current queue count is %d\n", pres->queue.Count);
        int fornt = pres->queue.Head->data;
        DeQueue(&pres->queue);
        VistQueue(&pres->queue);
        print("front is %d\n", fornt);
        printf("afeter cumsumer,current queue is %d\n", pres->queue.Count);
        pthread_mutex_unlock(&pres->mutex);
        pthread_cond_broadcast(&pres->cond);
        sleep(1);
    }
}
int main(int argc, char argv[])
{
    ShareRes res;
    memset(&res.queue, 0, sizeof(res.queue));
    pthread_mutex_init(&res.mutex, NULL);
    pthread_cond_init(&res.cond, NULL);
    for (int i = 0; i < 8; i++)
    {
        int data = rand() % 1000;
        enQueue(&res.queue, data);
        printf("data=%d\n", data);
        VistQueue(&res.queue);
    }
    printf("--------------------------------------------------------");
    pthread_t ptid[3];
    pthread_t ctid[2];
    for (int i = 0; i < 3; i++)
    {
        pthread_create(&ptid[i], NULL, producer, &res);
    }
    for (int i = 0; i < 2; i++)
    {
        pthread_create(&ctid[i], NULL, producer, &res);
    }
    pthread_join(ptid[0], NULL);
    pthread_join(ptid[1], NULL);
    pthread_join(ptid[2], NULL);
    pthread_join(ctid[0], NULL);
    pthread_join(ctid[1], NULL);
}